home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
GLOB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-08-18
|
5KB
|
219 lines
#ifdef UNIX
#include <stdio.h>
#include <time.h>
#include <sys/stat.h>
#include "dirutil.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: glob.c,v 1.10 1997/08/19 01:19:22 root Exp root $";
#endif
#ifdef __cplusplus
extern "C" {
#endif
extern uid_t geteuid (void);
extern gid_t getegid (void);
#ifdef __cplusplus
}
#endif
/*
* Second approximation of glob routine for JNOS/Linux
*/
static int ff1(const char *, const char *, const char *, struct ffblk *, int);
static char *
__ff_cat(const char *pfx, const char *sfx)
{
static char buf[1024];
buf[0] = '\0';
if (pfx && *pfx)
strcat(buf, pfx);
if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
strcat(buf, "/");
if (sfx && *sfx)
strcat(buf, sfx);
return buf;
}
int
findnext(struct ffblk *ff)
{
struct stat sb;
char *path;
int m;
/* special-case literal: if there's no pattern, just close the ff */
if (!ff->ff_pat || !ff->ff_dir)
return -1;
for (;;)
{
while ((ff->ff_cur = readdir(ff->ff_dir)) != 0 &&
wildmat(ff->ff_cur->d_name, ff->ff_pat, 0) == 0)
;
if (!ff->ff_cur)
{
(void) closedir(ff->ff_dir);
ff->ff_dir = 0;
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
return -1;
}
path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
stat(path, &sb) == -1 ||
(!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
(!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
!(ff->ff_sattr & FA_HIDDEN)))
{
j_free(path);
continue;
}
j_free(path);
if (geteuid() == sb.st_uid)
m = 0700;
else if (getegid() == sb.st_gid)
m = 0070;
else
m = 0007;
if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
continue;
ff->ff_ftime = *localtime(&sb.st_mtime);
ff->ff_fsize = sb.st_size;
if (S_ISDIR(sb.st_mode))
ff->ff_attrib = FA_DIREC;
else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
else
ff->ff_attrib = FA_NORMAL;
if (*ff->ff_cur->d_name == '.')
ff->ff_attrib |= FA_HIDDEN;
if (!(sb.st_mode & m & 0222))
ff->ff_attrib |= FA_RDONLY;
strncpy(ff->ff_name, ff->ff_cur->d_name, sizeof(ff->ff_name));
return 0;
}
}
static int
ff1(const char *prefix, const char *thedir, const char *pat, struct ffblk *ff, int attr)
{
char *pp, *cp, *ep, *xp;
char const *bp;
struct stat sb;
int m;
ff->ff_pfx = strdup(__ff_cat(prefix, thedir));
ff->ff_pat = 0;
ff->ff_dir = 0;
ff->ff_cur = 0;
ff->ff_name[0] = '\0';
ff->ff_sattr = attr;
cp = ep = pp = strdup(pat);
xp = 0;
bp = "";
for (; *cp; cp = ep)
{
while (*ep && *ep != '/') /* extract next component */
{
if (*ep == '?' || *ep == '*' || *ep == '[')
xp = ep; /* record presence of wildcard characters */
ep++;
}
if (*ep)
*ep++ = '\0';
if (xp) /* if we got a wildcard, abort */
break;
if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
continue;
xp = ff->ff_pfx; /* append component to prefix */
ff->ff_pfx = strdup(__ff_cat(xp, cp));
j_free(xp);
xp = 0;
bp = cp;
}
if (!xp) /* no wildcards; just return it */
{
strncpy(ff->ff_name, bp, sizeof(ff->ff_name));
if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
stat(ff->ff_pfx, &sb) == -1 ||
(!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
(!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
!(attr & FA_HIDDEN)))
{
j_free(pp);
j_free(ff->ff_pfx);
return -1;
}
/* unreadable files are system files */
/* don't check for root: if you run nos as root you're dead anyway */
if (geteuid() == sb.st_uid)
m = 0700;
else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
m = 0070;
else
m = 0007;
if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
{
j_free(ff->ff_pfx);
j_free(pp);
return -1;
}
ff->ff_ftime = *localtime(&sb.st_mtime);
ff->ff_fsize = sb.st_size;
if (S_ISDIR(sb.st_mode))
ff->ff_attrib = FA_DIREC;
else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
else
ff->ff_attrib = FA_NORMAL;
if (*bp == '.')
ff->ff_attrib |= FA_HIDDEN;
if (!(sb.st_mode & m & 0222))
ff->ff_attrib |= FA_RDONLY;
j_free(pp);
j_free(ff->ff_pfx);
ff->ff_pfx = 0;
return 0;
}
if (*ep) /* no subdirs this version */
{
j_free(ff->ff_pfx);
j_free(pp);
return -1;
}
ff->ff_pat = strdup(cp); /* the wildcarded component */
j_free(pp);
if ((ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")) == (DIR *)0)
{
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
return -1;
}
return findnext(ff);
}
int
findfirst(const char *pat, struct ffblk *ff, int attr)
{
return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
ff, attr);
}
#if 0
void
findlast(struct ffblk *ff)
{
if (!ff->ff_dir)
return;
(void) closedir(ff->ff_dir);
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
}
#endif
#endif /* UNIX */